package com.spring.campus_express_delivery.interceptor;

import com.alibaba.fastjson.JSONArray;
import com.spring.campus_express_delivery.entity.Users;
import com.spring.campus_express_delivery.util.JwtToken;
import com.spring.campus_express_delivery.util.MyUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * 验证token，是否登录  自己实现的登录拦截器  针对token进行拦截以及权限认证
 */
//@Component
public class TokenInterceptor implements HandlerInterceptor {
    MyUtil myUtil=new MyUtil();
    private Logger logger = LoggerFactory.getLogger(TokenInterceptor.class);
    /**
     * 忽略拦截的url
     */
    private String urls[] = {
            "/users/wx/register",
            "/users/wx/login",
            "/users/web/login",
            "/users/web/register",
            "/swagger-ui.html?urls.primaryName=GY1016#/",
            "/favicon.icon",
            "/index.html"
    };

    /**
     * 进入controller层之前拦截请求
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        String url = httpServletRequest.getRequestURI();
        //获取headers的token
        String token = httpServletRequest.getHeader("Authorization");
        String method = httpServletRequest.getMethod();
        if(token==null||"".equals(token)){
            logger.info(token);
            logger.info(url);
            logger.info(method);
            // 遍历需要忽略拦截的路径
            for (String item : this.urls){
                if (item.equals(url)){
                    return true;
                }
            }
            System.out.println("url:"+url+"被拦截了");
            return false;
        }else{
            if (!method.equals("OPTIONS")){
                // 查询验证token
                Users users = JwtToken.unsign(token, Users.class);
                if (users == null){
                    httpServletResponse.setCharacterEncoding("UTF-8");
                    httpServletResponse.setContentType("application/json; charset=utf-8");
                    PrintWriter out = null ;
                    try{

                        //使用fastjson  https://www.cnblogs.com/bingyimeiling/p/10790503.html
                        Map<String, Object> map = new HashMap<>();
                        map.put("msg","token不存在或已过期");
                        map.put("timestamp",myUtil.getTime());
                        map.put("code",403);
                        Object obj = JSONArray.toJSON(map);
                        String json = obj.toString();
                        out = httpServletResponse.getWriter();
                        out.append(json);
                        out.flush();
                        return false;
                    } catch (Exception e){
                        e.printStackTrace();
                        httpServletResponse.sendError(500);
                        return false;
                    }
                }
                //得到当前用户的权限（0是超级管理员，1是管理员，2是微信用户）
                int authority=users.getAuthority();
                System.out.println(authority);
                if(o instanceof HandlerMethod){
                    HandlerMethod handlerMethod = (HandlerMethod)o;
                    RequiredPermission permission = handlerMethod.getMethod().getDeclaredAnnotation(RequiredPermission.class);
                    if(permission != null){
                        /*
                        1、如果该接口的权限是超级管理员0的话，自定义注解的属性设置为0，那么如果用户是1和2的权限，那么1,2不小于等于0，所以他不是超级管理员
                        2、如果该接口的权限是管理员0和1的话，自定义注解的属性设置为1，那么如果用户他是超级管理员0 ，0是比1小的，如果是管理员1，那么1也是等于1的，所有有管理员的权限；如果是微信用户2，那么2不小于等于1，所以他不具有管理员权限
                        3、如果该接口的权限是微信用户权限2的话，自定义注解的属性设置为2，那么如果用户是管理员0,1不小于等于2，所以只能是微信用户权限的可以
                         */
                        if(authority<=permission.value()){//如果当前用户的权限大于等于注解上的权限,有管理员权限访问
                            return true;//
                        }
                        else{
                            httpServletResponse.setCharacterEncoding("UTF-8");
                            httpServletResponse.setContentType("application/json; charset=utf-8");
                            //使用fastjson  https://www.cnblogs.com/bingyimeiling/p/10790503.html
                            Map<String, Object> map = new HashMap<>();
                            map.put("msg","没有权限,请联系管理员");
                            map.put("timestamp",myUtil.getTime());
                            map.put("code",403);
                            Object obj = JSONArray.toJSON(map);
                            String json = obj.toString();
                            PrintWriter out = null ;
                            out = httpServletResponse.getWriter();
                            out.append(json);
                            out.flush();
                            return  false;
                        }
                    }
                }
                return true;
            }
        }
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        // System.out.println("视图渲染之后的操作");
    }
}

